import 'dart:convert';

import 'package:event_bus/event_bus.dart';
import 'package:flutter/services.dart';
import 'package:flutter_city_picker/city_picker.dart';
import 'package:flutter_city_picker/model/address.dart';
import 'package:shirne_app/utils/core.dart';

class CityPickerResult {
  String? provinceCode;
  String? provinceName;
  String? cityCode;
  String? cityName;
  String? districtCode;
  String? districtName;

  String? streetCode;
  String? streetName;
  CityPickerResult({
    this.provinceCode,
    this.provinceName,
    this.cityCode,
    this.cityName,
    this.districtCode,
    this.districtName,
    this.streetCode,
    this.streetName,
  });

  Map toJson() => {
        "provinceCode": provinceCode,
        "provinceName": provinceName,
        "cityCode": cityCode,
        "cityName": cityName,
        "districtCode": districtCode,
        "districtName": districtName,
        "streetCode": streetCode,
        "streetName": streetName,
      };

  @override
  String toString() => toJson().toString();
}

class CityPickerDriver extends EventBus implements CityPickerListener {
  Map<String, List<AddressNode>>? cityData;
  final result = CityPickerResult();

  @override
  void onFinish(List<AddressNode> nodes) {
    fire(
      CityPickerResult(
        provinceCode: nodes.atOrNull(0)?.code,
        provinceName: nodes.atOrNull(0)?.name,
        cityCode: nodes.atOrNull(1)?.code,
        cityName: nodes.atOrNull(1)?.name,
        districtCode: nodes.atOrNull(2)?.code,
        districtName: nodes.atOrNull(2)?.name,
        streetCode: nodes.atOrNull(3)?.code,
        streetName: nodes.atOrNull(3)?.name,
      ),
    );
  }

  @override
  Future<List<AddressNode>> onDataLoad(
    int index,
    String code,
    String name,
  ) async {
    if (cityData == null) {
      Map<String, dynamic> data =
          await rootBundle.loadStructuredData<Map<String, dynamic>>(
        "assets/json/areas.json",
        (value) async => jsonDecode(value),
      );
      cityData = data.map(
        (key, value) => MapEntry(
          key.split(',').last,
          (value as Map)
              .entries
              .map<AddressNode>(
                (item) => AddressNode(name: item.value, code: item.key),
              )
              .toList(),
        ),
      );
    }

    return cityData?[code] ?? <AddressNode>[];
  }
}
